package com.heaven.ojcodesandbox.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.heaven.ojcodesandbox.model.ExecuteMessage;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 执行进程并获取信息
 * 进程工具类
 * @Author HeavenDirt
 * @Date 2024/7/25 22:47
 */
public class ProcessUtils {

    /**
     * 执行进程并获取信息
     *
     * @param runProcess
     * @param opName     操作名称
     * @return ExecuteMessage
     * @author HeavenDirt
     * @date 2024/7/25 23:13
     */
    public static ExecuteMessage runProcessAndGetMessage(Process runProcess, String opName) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            int exitValue = runProcess.waitFor();
            executeMessage.setExitValue(exitValue);
            if (exitValue == 0) {
                //正常退出
                System.out.println(opName + "成功");
                //分批获取进程输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                //StringBuilder compileOutputStringBuilder = new StringBuilder();
                List<String> outputList = new ArrayList<>();
                //逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    //compileOutputStringBuilder.append(compileOutputLine).append(StrUtil.CRLF);
                    outputList.add(compileOutputLine);
                }

                executeMessage.setMessage(StringUtils.join(outputList, "\n"));
            } else {
                //异常退出
                System.out.println(opName + "失败，错误码:" + exitValue);
                //分批获取进程正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                //StringBuilder compileOutputStringBuilder = new StringBuilder();
                List<String> outputList = new ArrayList<>();
                //逐行读取
                String compileOutputLine;
                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    //compileOutputStringBuilder.append(compileOutputLine).append(StrUtil.CRLF);
                    outputList.add(compileOutputLine);
                }
                executeMessage.setMessage(StringUtils.join(outputList, "\n"));

                //分批获取进程错误输出
                BufferedReader erroeBufferedReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
                //StringBuilder errorCompileOutputStringBuilder = new StringBuilder();
                List<String> errorOutputList = new ArrayList<>();
                //逐行读取
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = erroeBufferedReader.readLine()) != null) {
                    //errorCompileOutputStringBuilder.append(errorCompileOutputLine).append(StrUtil.CRLF);
                    errorOutputList.add(errorCompileOutputLine);
                }
                executeMessage.setErrorMessage(StringUtils.join(errorOutputList, "\n"));
            }
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return executeMessage;
    }

    /**
     * 执行交互式进程并获取信息
     *
     * @param runProcess
     * @param opName     操作名称
     * @return ExecuteMessage
     * @author HeavenDirt
     * @date 2024/7/25 23:14
     */
    public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess, String opName, String input) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {

            OutputStream outputStream = runProcess.getOutputStream();

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            String[] s = input.split(" ");
            outputStreamWriter.write(StrUtil.join("\n", s) + "\n");
            outputStreamWriter.flush();

            InputStream inputStream = runProcess.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            //逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine).append("\n");
            }
            executeMessage.setMessage(compileOutputStringBuilder.toString());

            //资源释放
            outputStreamWriter.close();
            outputStream.close();
            inputStream.close();
            runProcess.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return executeMessage;
    }
}